package practicaspl.dos;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Stack;

import practicaspl.dos.Files;


public class Analizador {

	private File ficherocodigo;
	private FileReader fread;
	private BufferedReader buffer;
	private Stack<Integer> pila;
	private ArrayList<Bloque> bloques;
	private ListAparaciones apariciones;
	
	public Analizador(){
		ficherocodigo = null;
		fread = null;
		buffer = null;
		pila = new Stack<Integer>();
		bloques = new ArrayList<Bloque>();
		apariciones = new ListAparaciones();
	}
	
	public File getFicherocodigo() {
		return ficherocodigo;
	}

	public void setFicherocodigo(File ficherocodigo) {
		this.ficherocodigo = ficherocodigo;
	}

	public FileReader getFread() {
		return fread;
	}

	public void setFread(FileReader fread) {
		this.fread = fread;
	}

	public BufferedReader getBuffer() {
		return buffer;
	}

	public void setBuffer(BufferedReader buffer) {
		this.buffer = buffer;
	}
	
	public Stack<Integer> getPila() {
		return pila;
	}

	public void setPila(Stack<Integer> pila) {
		this.pila = pila;
	}

	public ArrayList<Bloque> getBloques() {
		return bloques;
	}

	public void setBloques(ArrayList<Bloque> bloques) {
		this.bloques = bloques;
	}
	
	public String mostrarBloques(ArrayList<Bloque> bloques){
		
		String resultado = "";
		for (int i = 0; i < bloques.size(); i++) {
			System.out.println("Bloque " + (i+1));
			System.out.println(" con profundidad " + bloques.get(i).getProfundidad());
			System.out.println(" desde línea " + bloques.get(i).getInicio());
			System.out.println(" hasta línea " + bloques.get(i).getFin());
			resultado += ("Bloque " + (i+1) + "\n desde línea " + bloques.get(i).getInicio() + "\n hasta línea " + bloques.get(i).getFin() + "\n");
		}
		return resultado;
	}
	
	public boolean ContieneSimbolo(HashSet<Character> conjunto, char simbolo) {
		
		return(conjunto.contains(simbolo));
		
	}
	
	public boolean ContienePalabra(HashSet<String> conjunto, String palabra) {
		
		return(conjunto.contains(palabra));
		
	}
	
	public boolean Analiza(String ficherocode) throws IOException {
		
    	Files ficheros = new Files();
    	ficheros.leer_simbolos("simbolos.txt");
    	ficheros.leer_palabras("reservadas.txt");
 
		setFicherocodigo(new File (ficherocode));
		fread = new FileReader (ficherocode);
		buffer = new BufferedReader(fread);
		
		int contador_linea = 1;
		int profundidad = 0;
		String aux = "";
		String linea = "";
	    while((linea = buffer.readLine())!= null)
	    {
	    	for(int i = 0; i < linea.length(); i++) {
	    		if ((linea.charAt(i) != '\n') && (linea.charAt(i) !='\t')) {
		    		if (ContieneSimbolo(ficheros.getSimbolos().getColecc_simbolos(), linea.charAt(i))) {
		    			aux += linea.charAt(i);
		    		}
		    		else {
		    			if (!ContieneSimbolo(ficheros.getSimbolos().getColecc_simbolos_p(),linea.charAt(i))) {
		    				System.out.println("Error! Símbolo "+ linea.charAt(i) +
		    						           " no contenido en fichero de símbolos");
		    				return false;
		    			}
		    			else {
		    				if (ContienePalabra(ficheros.getPalabrasReservadas().getPalabras(), aux)) {
//		    					System.out.println(aux + " en línea " + contador_linea);
		    					apariciones.insertar(aux, contador_linea);
		    				}
		    				
	    					if (linea.charAt(i) == '{') {
	    						pila.push(contador_linea);
	    						profundidad++;
	    					}
	    					if (linea.charAt(i) == '}') {
	    						Bloque bloque_aux = new Bloque();	    						
	    						bloque_aux.setInicio(pila.pop());
	    						bloque_aux.setFin(contador_linea);
	    						bloque_aux.setProfundidad(profundidad);
	    						bloques.add(bloque_aux);
	    						profundidad--;
		    				}
		    				aux = "";
		    			}	
		    		}
	    		}
	    	}
	    	contador_linea++;
	    }
	    apariciones.MostrarApariciones();
	    return true;
	}


}
